package com.yxy.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.yxy.constant.MessageConstant;
import com.yxy.constant.StatusConstant;
import com.yxy.domain.dto.SportDTO;
import com.yxy.domain.dto.SportListDTO;
import com.yxy.domain.po.SportList;
import com.yxy.domain.po.Sports;
import com.yxy.domain.po.SportsType;
import com.yxy.domain.vo.SportAllVO;
import com.yxy.domain.vo.SportListVo;
import com.yxy.domain.vo.SportTypeVO;
import com.yxy.domain.vo.SportVO;
import com.yxy.exception.SportException;
import com.yxy.mapper.SportMapper;
import com.yxy.service.SportService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class SportServiceImpl implements SportService {

    private final SportMapper sportMapper;
    public SportServiceImpl(SportMapper sportMapper){
        this.sportMapper = sportMapper;
    }

    /**
     * 获取运动类型
     * @return
     */
    @Override
    public List<SportTypeVO> getSportType() {
        List<SportsType> list = sportMapper.getSportType();
        if(list.isEmpty()){
            throw new SportException(MessageConstant.SPORT_TYPE_NOT_FOUND);
        }
        List<SportTypeVO> vo = BeanUtil.copyToList(list, SportTypeVO.class);
        vo.forEach(item -> {
            item.setMetricType(sportMapper.getMetricTypeByid(item.getMetricTypeId()).getType());
        });
        return vo;
    }

    /**
     * 获取运动
     * @param id
     * @return
     */
    @Transactional
    @Override
    public SportVO getSport(Integer id) {
        // 查询用户当天是否运动过
        Sports sports = sportMapper.getSportByIdAndCreateTime(id, LocalDate.now());
        if(sports == null){
            // 当天首次则先创建运动记录
            Sports sport = Sports.builder()
                    .userId(id)
                    .hours(StatusConstant.DEFAULT_TIME)
                    .minutes(StatusConstant.DEFAULT_TIME)
                    .seconds(StatusConstant.DEFAULT_TIME)
                    .isFirst(StatusConstant.DEFAULT_TIME)
                    .createTime(LocalDate.now())
                    .build();
            sportMapper.insert(sport);
            return BeanUtil.copyProperties(sport, SportVO.class);
        }
        SportVO sportVO = BeanUtil.copyProperties(sports, SportVO.class);
        // 查询运动列表
        List<SportList> sportList = sportMapper.selectSportListBySportId(sports.getId());
        if(sportList != null){
            List<SportListVo> sportListVos = BeanUtil.copyToList(sportList, SportListVo.class);
            // 给每个运动都加上判断类型
            sportListVos.forEach(item  -> {
                item.setMetricType(sportMapper.getMetricTypeByid(item.getMetricTypeId()).getType());
            });
            sportVO.setSportList(sportListVos);
        }else{
            sportVO.setSportList(null);
        }
        return sportVO;
    }

    /**
     * 刷新运动
     * @param sportDTO
     */
    @Transactional
    @Override
    public void refreshSport(SportDTO sportDTO) {
        // 向运动表中更新数据
        Sports sports = Sports.builder()
                .id(sportDTO.getId())
                .hours(sportDTO.getHours())
                .minutes(sportDTO.getMinutes())
                .seconds(sportDTO.getSeconds())
                .isFirst(StatusConstant.ENABLE)
                .build();
        sportMapper.update(sports);
        // 向运动列表表中插入数据
        // 先判断是否存在，若不存在先新增修改
        SportListDTO sportListDTO = sportDTO.getList().get(0);
        SportList sportList = sportMapper.getSportListBSportIdAndSportTypeId(sportDTO.getId(), sportListDTO.getSportsTypeId());
        if(sportList == null){
            // 新增
            SportList sportListI = BeanUtil.copyProperties(sportListDTO, SportList.class);
            sportListI.setSportsId(sportDTO.getId());
            sportMapper.insertSportList(sportListI);
        }else{
            // 更新
            sportList.setHours(sportListDTO.getHours());
            sportList.setMinutes(sportListDTO.getMinutes());
            sportList.setSeconds(sportListDTO.getSeconds());
            sportList.setData(sportListDTO.getData());
            sportMapper.updateSportList(sportList);
        }
    }

    /**
     * 根据运动id获取运动详情
     * @param id
     * @return
     */
    @Override
    public List<SportListVo> getDetail(Integer id) {
        List<SportList> list = sportMapper.selectSportListBySportId(id);
        List<SportListVo> voList = BeanUtil.copyToList(list, SportListVo.class);
        voList.forEach(item -> {
            item.setMetricType(sportMapper.getMetricTypeByid(item.getMetricTypeId()).getType());
        });
        return voList;
    }

    /**
     * 获取所有运动
     * @return
     */
    @Override
    public List<SportAllVO> sportAll() {
        List<SportAllVO> list = sportMapper.selectAll();
        // 1. 按 userId 分组，计算每个用户的总时间
        Map<Integer, int[]> userTotalTimeMap = list.stream()
                .collect(Collectors.groupingBy(
                        SportAllVO::getUserId,
                        Collectors.reducing(
                                new int[3], // [totalHours, totalMinutes, totalSeconds]
                                vo -> new int[]{vo.getHours(), vo.getMinutes(), vo.getSeconds()},
                                (a, b) -> {
                                    int totalSeconds = a[2] + b[2];
                                    int carryMinutes = totalSeconds / 60;
                                    int remainingSeconds = totalSeconds % 60;

                                    int totalMinutes = a[1] + b[1] + carryMinutes;
                                    int carryHours = totalMinutes / 60;
                                    int remainingMinutes = totalMinutes % 60;

                                    int totalHours = a[0] + b[0] + carryHours;
                                    return new int[]{totalHours, remainingMinutes, remainingSeconds};
                                }
                        )
                ));
        // 2. 更新每个 VO 对象的 totalTime
        Set<Integer> seenIds = new HashSet<>();
        List<SportAllVO> result = new ArrayList<>();

        for (SportAllVO vo : list) {
            if (seenIds.add(vo.getUserId())) { // 如果 id 未出现过，添加到结果列表
                int[] totalTime = userTotalTimeMap.get(vo.getUserId());
                // 查询每个用户当天的运动时长
                Sports sports = sportMapper.getByUserIdAndCurrentDate(vo.getUserId(), LocalDate.now());
                SportAllVO build = SportAllVO.builder()
                        .userId(vo.getUserId())
                        .nickname(vo.getNickname())
                        .hours(sports == null ? 0 : sports.getHours())
                        .minutes(sports == null ? 0 : sports.getMinutes())
                        .seconds(sports == null ? 0 : sports.getSeconds())
                        .totalTime(formatTime(totalTime[0], totalTime[1], totalTime[2]))
                        .build();
                result.add(build);
            }
        }
        return result;
    }
    // 格式化时间为 "Xh Ym Zs"
    private String formatTime(int hours, int minutes, int seconds) {
        StringBuilder sb = new StringBuilder();
        if (hours > 0) sb.append(hours).append("h ");
        if (minutes > 0) sb.append(minutes).append("m ");
        if (seconds > 0 || sb.isEmpty()) sb.append(seconds).append("s");
        return sb.toString().trim();
    }
}
